<?php

namespace App\Services;

use App\Extend\IPweb;
use App\Jobs\SendNotificationJob;
use App\Jobs\StaticProxyRenewalJob;
use App\Models\OrderInfo;
use App\Models\ProxyUser;
use App\Models\StaticProxyDetail;
use App\Models\StaticRegion;
use App\Models\TrafficDetail;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Queue;

class ProxyService
{
    protected $IPweb;

    public function __construct()
    {
        $this->IPweb = new IPweb();
    }

    // 创建账号
    public function addUser($user_id)
    {
        $user = User::find($user_id);
        if (empty($user)) {
            return false;
        }
        $result = $this->IPweb->addUser($user->username);
        if ($result && $result['code'] == 200) {
            $user->customer_id = $result['customerId'];
            $user->auth_password = $result['password'];
            $user->auth_token = $result['Token'];
            $user->save();
            return [
                'code' => 0,
                'msg' => '操作成功'
            ];
        }
        return [
            'code' => -1,
            'msg' => $result['msg']
        ];
    }

    // 充值流量
    public function rechargeTraffic($user_id, $order_nu, $trafficCount)
    {
        $user = User::find($user_id);
        if (empty($user) || empty($user->customer_id)) {
            return [
                'code' => -1,
                'msg' => '用户信息不全'
            ];
        }
        $result = $this->IPweb->rechargeTrafficCount($user->customer_id, $order_nu, $trafficCount);
        if ($result && $result['code'] == 200) {
            return [
                'code' => 0,
                'msg' => '充值成功'
            ];
        }
        return [
            'code' => -1,
            'msg' => $result['msg']
        ];
    }

    // 创建子账号
    public function proxyUserList($user_id)
    {
        $user = User::find($user_id);
        if (empty($user)) {
            return false;
        }
        $result = $this->IPweb->getUserList($user->auth_token);
        if ($result && $result['code'] == 200) {
            return $result['data'];
        }
        return [];
    }

    // 创建子账号
    public function createProxyUser($user_id, $password = '000000')
    {
        try {
            $user = User::find($user_id);
            if (empty($user)) {
                throw new \Exception('用户不存在');
            }
            if (floatval($user->total_traffic) <= 0) {
                throw new \Exception('账户无流量');
            }

            $username = 'IPX' . $user_id;
            $proxyUser = ProxyUser::firstOrCreate(['user_id' => $user_id]);
            if ($proxyUser->status == 1) {
                return [
                    'code' => 0,
                    'msg' => '操作成功'
                ];
            }

            $result = $this->IPweb->addChildAccount($username, $password, $user->auth_token);
            if ($result && $result['code'] == 200) {
                $proxyUser->username = $username;
                $proxyUser->pwd = Crypt::encryptString($password);
                $proxyUser->status = 1;
                $proxyUser->save();
            } else {
                throw new \Exception($result['msg']);
            }
        } catch (\Exception $e) {
            return [
                'code' => -1,
                'msg' => $e->getMessage()
            ];
        }
        return [
            'code' => 0,
            'msg' => '操作成功'
        ];
    }

    // 修改子账号密码
    public function updateProxyUser($user_id, $password)
    {
        $user = User::find($user_id);
        if (empty($user)) {
            return false;
        }
        $proxyUser = ProxyUser::where('user_id', $user_id)->first();
        if (empty($proxyUser)) {
            return false;
        }
        if (Crypt::decryptString($proxyUser->pwd) == $password) {
            return $proxyUser;
        }
        $result = $this->IPweb->updateChildPwd($proxyUser->username, $password, $user->auth_token);
        if ($result && $result['code'] == 200) {
            $proxyUser->pwd = Crypt::encryptString($password);
            $proxyUser->save();
            return $proxyUser;
        }
        return false;
    }

    // 生成代理规则
    public function createProxy($user_id, $quantity, $time, $country_code, $region_code, $city_code)
    {
        $username = ProxyUser::where('user_id', $user_id)->value('username');
        $account = [];
        for ($i = 0; $i < $quantity; $i++) {
            $sid = substr(time(), 6) . mt_rand(1000, 9999);
            if (!empty($region_code) && !empty($city_code)) {
                $child_account = $username . '_custom_zone_' . $country_code . '_st_' . $region_code . '_city_' . $city_code . '_sid_' . $sid . '_time_' . $time;
            } else {
                $intercontinental = '';
                $intercontinental_config = config('intercontinental');
                if (in_array($country_code, $intercontinental_config['asia'])) {
                    $intercontinental = 'asia';
                } elseif (in_array($country_code, $intercontinental_config['europe'])) {
                    $intercontinental = 'europe';
                } elseif (in_array($country_code, $intercontinental_config['america'])) {
                    $intercontinental = 'america';
                } elseif (in_array($country_code, $intercontinental_config['africa'])) {
                    $intercontinental = 'africa';
                }
                if (!empty($intercontinental)) {
                    $child_account = $username . '_custom_zone_' . $intercontinental . '_sid_' . $sid . '_time_' . $time;
                } else {
                    $child_account = $username . '_custom_zone_global_sid_' . $sid . '_time_' . $time;
                }
            }
            $account[] = $child_account;
        }

        return $account;
    }

    // 多类型流量查询
    public function getFlowTotalFull()
    {
        User::chunkById(100, function ($data) {
            foreach ($data as $user) {
                if ($user->id == 100000) {
                    $token = '29Y1SCZDN3Z91WRSQY9L068XI2T4A1VD';
                } else {
                    $token = $user->auth_token;
                }
                if (empty($token)) {
                    continue;
                }
                $result = $this->IPweb->getFlowTotalFull($token);
                if ($result && $result['code'] == 200 && !empty($result['data'])) {
                    $data = $result['data']['account'];
                    $user->traffic = $data['residualFlow'];
                    $user->total_traffic = $data['flowCount'];
                    $user->consume_traffic = $data['consumeFlow'];
                    $user->save();
                }
            }
        });
    }

    // 流量消费详情查询
    public function getFlowConsumeDetail($date)
    {
        $startDate = date('Y-m-d', strtotime($date));
        $endDate = date('Y-m-d', strtotime($date));
        User::chunkById(100, function ($data) use ($startDate, $endDate) {
            foreach ($data as $user) {
                $result = $this->IPweb->getFlowConsumeDetail($user->auth_token, $startDate, $endDate);
                if ($result && $result['code'] == 200 && !empty($result['data'])) {
                    foreach ($result['data'] as $item) {
                        TrafficDetail::updateOrCreate(
                            [
                                'user_id' => $user->id,
                                'create_day' => $item['date']
                            ],
                            [
                                'download_flow' => $item['downloadFlow'],
                                'upload_flow' => $item['uploadFlow']
                            ]
                        );
                    }
                }
            }
        });
    }

    public function updateProxyUserStatus($user_id, $status)
    {
        $auth_token = User::where('id', $user_id)->value('auth_token');
        $proxyUser = ProxyUser::where('user_id', $user_id)->first();
        $result = $this->IPweb->updateChildStatus($proxyUser->username, $status, $auth_token);
        if ($result && $result['code'] == 200) {
            $proxyUser->status = $status;
            $proxyUser->save();
            return true;
        }
        return false;
    }

    public function enabledProxyUser($user_id)
    {
        $user = User::find($user_id);
        $result = $this->IPweb->changeStatus($user->customer_id, 0);
        if ($result && $result['code'] == 200) {
            return true;
        }
        return false;
    }

    public function getStaticRegions()
    {
        $country_result = $this->IPweb->getStaticRegions();
        if (!empty($country_result) && $country_result['code'] == 200) {
            foreach ($country_result['data'] as $region) {
                $static_region = StaticRegion::firstOrCreate([
                    'code' => $region
                ]);
            }
        }
    }

    // 购买静态代理
    public function createStaticOrder($user_id, $order_nu)
    {
        try {
            $user = User::find($user_id);
            if (empty($user) || empty($user->customer_id)) {
                return [
                    'code' => -1,
                    'msg' => '用户信息不全'
                ];
            }
            $orderInfo = OrderInfo::where('order_nu', $order_nu)->where('user_id', $user_id)->first();
            if (empty($orderInfo)) {
                return [
                    'code' => -1,
                    'msg' => '订单号错误'
                ];
            }
            $extend = json_decode($orderInfo->extend, true);
            if (empty($orderInfo->is_renew)) {
                // 新订单
                if ($extend['days'] > 30) {
                    $extend['days'] = 30;
                }
                $result = $this->IPweb->createStaticOrder($extend['country_code'], $extend['days'], $extend['quantity'], $extend['line_type'], $extend['business'], $user->customer_id);
                if ($result && $result['code'] == 200) {
                    $data = $result['data'];
                    $carbon = Carbon::parse($data['expired_at']);
                    $expired_time = $carbon->format('Y-m-d H:i:s');

                    foreach ($data['allots'] as $key => $allot) {
                        StaticProxyDetail::create([
                            'user_id' => $user_id,
                            'order_nu' => $order_nu,
                            'sort' => $key + 1,
                            'country_code' => $extend['country_code'],
                            'business' => $extend['business'],
                            'line_type' => $extend['line_type'],
                            'service_order_nu' => $data['order_id'],
                            'ip' => $allot['ip'],
                            'domain' => $allot['node_domain'],
                            'port' => $allot['node_port'],
                            'account' => $allot['account'],
                            'password' => $allot['password'],
                            'expired_time' => $expired_time,
                            'status' => 1
                        ]);
                    }

                    Queue::later(30, new StaticProxyRenewalJob($user_id, $order_nu));

                    return [
                        'code' => 0,
                        'msg' => '充值成功'
                    ];
                } else {
                    $content = "*充值静态代理失败*\n订单号：{$orderInfo->order_nu}\n错误原因：{$result['message']}";
                    dispatch(new SendNotificationJob($content));
                    return [
                        'code' => -1,
                        'msg' => '充值失败'
                    ];
                }
            } else {
                // 后台批量续期
                if (!empty($extend['main_order_nu'])) {
                    $details = StaticProxyDetail::where('user_id', $user_id)->where('order_nu', $extend['main_order_nu'])->get();
                    foreach ($details as $detail) {
                        $result = $this->IPweb->staticOrderRenew($detail->ip, $extend['days'], $user->customer_id);
                        if ($result && $result['code'] == 200) {
                            $data = $result['data'];
                            $carbon = Carbon::parse($data['expired_at']);
                            $expired_time = $carbon->format('Y-m-d H:i:s');

                            $detail->expired_time = $expired_time;
                            $detail->status = 1;
                            $detail->save();
                        } else {
                            $content = "*静态代理续期失败*\n订单号：{$orderInfo->order_nu}\n错误原因：{$result['message']}";
                            dispatch(new SendNotificationJob($content));
                            return [
                                'code' => -1,
                                'msg' => '续期失败'
                            ];
                        }
                    }
                    return [
                        'code' => 0,
                        'msg' => '充值成功'
                    ];
                } else {
                    // 单IP续期
                    $staticProxyDetail = StaticProxyDetail::where('user_id', $user_id)->where('ip', $extend['ip'])->first();
                    if (empty($staticProxyDetail)) {
                        return [
                            'code' => -1,
                            'msg' => '订单号错误'
                        ];
                    }
                    if ($extend['days'] > 30) {
                        $extend['days'] = 30;
                    }
                    $result = $this->IPweb->staticOrderRenew($extend['ip'], $extend['days'], $user->customer_id);
                    if ($result && $result['code'] == 200) {
                        $data = $result['data'];
                        $carbon = Carbon::parse($data['expired_at']);
                        $expired_time = $carbon->format('Y-m-d H:i:s');

                        $staticProxyDetail->expired_time = $expired_time;
                        $staticProxyDetail->status = 1;
                        $staticProxyDetail->save();

                        Queue::later(30, new StaticProxyRenewalJob($user_id, $order_nu, true));

                        return [
                            'code' => 0,
                            'msg' => '充值成功'
                        ];
                    } else {
                        $content = "*静态代理续期失败*\n订单号：{$orderInfo->order_nu}\n错误原因：{$result['message']}";
                        dispatch(new SendNotificationJob($content));
                        return [
                            'code' => -1,
                            'msg' => '充值失败'
                        ];
                    }
                }
            }
        } catch (\Exception $e) {
            Log::error('静态代理充值失败 msg：' . $e->getMessage() . '，line：' . $e->getLine());
            return [
                'code' => -1,
                'msg' => '充值失败'
            ];
        }
    }
}
